package com.example.financechain.Utils;

import com.example.financechain.config.CacheKeyManager;
import com.example.financechain.domain.entity.Role;
import org.hyperledger.fabric.gateway.Gateway;
import org.hyperledger.fabric.gateway.Identities;
import org.hyperledger.fabric.gateway.Wallet;
import org.hyperledger.fabric.gateway.Wallets;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.PrivateKey;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Properties;

@Component
public class GatewayUtilss {

    public  Gateway.Builder build(Role role) throws IOException, InvalidKeyException, CertificateException {
        Properties properties = new Properties();
        InputStream inputStream = GatewayUtilss.class.getResourceAsStream("/fabric.config.properties");
        properties.load(inputStream);
        String networkConfigPath = properties.getProperty("networkConfigPath");


        X509Certificate certificate = null;
        PrivateKey privateKey = null;

        InputStream inputStream3 = null;
        if (role.getRoleCertification().equals(CacheKeyManager.FINANCEORG)){

            InputStream inputStream1 = GatewayUtilss.class.getResourceAsStream(properties.getProperty("Org1_certificatePath"));
             certificate = readX509Certificate(inputStream1);

            InputStream inputStream2 = GatewayUtilss.class.getResourceAsStream(properties.getProperty("Org1_privateKeyPath"));
            //String privateKeyPath = properties.getProperty("privateKeyPath");
             privateKey = getPrivateKey(inputStream2);

             inputStream3 = GatewayUtilss.class.getResourceAsStream(networkConfigPath);
        }else if (role.getRoleCertification().equals(CacheKeyManager.ENTERPRISE_2)){
            InputStream inputStream1 = GatewayUtilss.class.getResourceAsStream(properties.getProperty("Org2_certificatePath"));
             certificate = readX509Certificate(inputStream1);

            InputStream inputStream2 = GatewayUtilss.class.getResourceAsStream(properties.getProperty("Org2_privateKeyPath"));
            //String privateKeyPath = properties.getProperty("privateKeyPath");
             privateKey = getPrivateKey(inputStream2);

             inputStream3 = GatewayUtilss.class.getResourceAsStream(networkConfigPath);
        }else if (role.getRoleCertification().equals(CacheKeyManager.ENTERPRISE_3)){
            InputStream inputStream1 = GatewayUtilss.class.getResourceAsStream(properties.getProperty("Org3_certificatePath"));
             certificate = readX509Certificate(inputStream1);

            InputStream inputStream2 = GatewayUtilss.class.getResourceAsStream(properties.getProperty("Org3_privateKeyPath"));
            //String privateKeyPath = properties.getProperty("privateKeyPath");
             privateKey = getPrivateKey(inputStream2);

             inputStream3 = GatewayUtilss.class.getResourceAsStream(networkConfigPath);
        }else if (role.getRoleCertification().equals(CacheKeyManager.ENTERPRISE_4)){
            InputStream inputStream1 = GatewayUtilss.class.getResourceAsStream(properties.getProperty("Org4_certificatePath"));
             certificate = readX509Certificate(inputStream1);

            InputStream inputStream2 = GatewayUtilss.class.getResourceAsStream(properties.getProperty("Org4_privateKeyPath"));
            //String privateKeyPath = properties.getProperty("privateKeyPath");
            privateKey = getPrivateKey(inputStream2);

             inputStream3 = GatewayUtilss.class.getResourceAsStream(networkConfigPath);
        }else if (role.getRoleCertification().equals(CacheKeyManager.ENTERPRISE_5)){
            InputStream inputStream1 = GatewayUtilss.class.getResourceAsStream(properties.getProperty("Org5_certificatePath"));
             certificate = readX509Certificate(inputStream1);

            InputStream inputStream2 = GatewayUtilss.class.getResourceAsStream(properties.getProperty("Org5_privateKeyPath"));
            //String privateKeyPath = properties.getProperty("privateKeyPath");
             privateKey = getPrivateKey(inputStream2);

             inputStream3 = GatewayUtilss.class.getResourceAsStream(networkConfigPath);
        }



        //这一步相当于生成一个user身份去调用
        Wallet wallet = Wallets.newInMemoryWallet();

        wallet.put(role.getRoleName(), Identities.newX509Identity(role.getRoleCertification(),certificate,privateKey));

        //根据connection.json 获取Fabric网络连接对象

        Gateway.Builder builder = Gateway.createBuilder()
                .identity(wallet, role.getRoleName())
                .networkConfig(inputStream3);
        //连接网关
        return builder;
    }

    private  X509Certificate readX509Certificate(final InputStream inputStream) throws IOException, CertificateException {

        try (Reader certificateReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);) {
            return Identities.readX509Certificate(certificateReader);
        }
    }

    private  PrivateKey getPrivateKey(final InputStream inputStream) throws IOException, InvalidKeyException {
        try (Reader privateKeyReader = new InputStreamReader(inputStream,StandardCharsets.UTF_8)) {
            return Identities.readPrivateKey(privateKeyReader);
        }
    }
}
